import { getMapId } from './getMapId/App';
import { light_show } from './light_show';
import { voxel_countdown } from './start_show';
const findOnlineId = (userId: string) =>
    world.querySelectorAll('player').find((e) => e.player.userId === userId);
const findOnlineName = (name: string) =>
    world.querySelectorAll('player').find((e) => e.player.name === name);

/**
 * 发送客户端时间
 * @param entity
 * @param type
 * @param data
 */
function sendClient(
    entity: GamePlayerEntity | GamePlayerEntity[],
    type: string,
    data: object | string | number
) {
    remoteChannel.sendClientEvent(entity, {
        type,
        data,
    });
}

/**
 * 显示UI屏幕
 * @param entity
 * @param ui_name
 */
function showScreen(entity: GamePlayerEntity, ui_name: string) {
    sendClient(entity, 'showScreen', ui_name);
}
/**
 * 隐藏UI屏幕
 * @param entity
 * @param ui_name
 */
function hideScreen(entity: GamePlayerEntity, ui_name: string) {
    sendClient(entity, 'hideScreen', ui_name);
}

/**
 * 显示UI
 * @param entity
 * @param screen
 * @param ui_name
 */
function showUI(entity: GamePlayerEntity, screen: string, ui_name: string) {
    sendClient(entity, 'showUI', { screen, ui_name });
}

/**
 * 隐藏UI
 * @param entity
 * @param screen
 * @param ui_name
 */
function hideUI(entity: GamePlayerEntity, screen: string, ui_name: string) {
    sendClient(entity, 'hideUI', { screen, ui_name });
}

/**
 * 管理员类型枚举
 */
enum ADMIN_TYPE {
    PEOPLE = '人员管理',
    PATROL = '巡逻管理',
    BACKEND = '后台管理',
    BLACK = '被拉黑',
    CAMERA = '直播',
}
/**
 * 初始管理员
 */
const admin_setup: adminData[] = [
    {
        userId: '12742619',
        name: '反',
        admin: ADMIN_TYPE.PEOPLE,
        time: Date.now() * 100,
    }, // 反
    {
        userId: '13048627',
        name: 'shen梦',
        admin: ADMIN_TYPE.PEOPLE,
        time: Date.now() * 100,
    },
];

/**
 * 管理员数据
 */
interface adminData {
    /**
     * 管理员ID
     */
    userId: string;
    /**
     * 管理员昵称
     */
    name: string;
    avatar?: string;
    /**
     * 管理员类型
     */
    admin: ADMIN_TYPE;
    /**
     * 管理员有效期
     */
    time: number;
}

const adminStorage = storage.getGroupStorage<adminData[]>('admin');
let admin_data: adminData[] = admin_setup;
const backend_pos = new GameVector3(41, 52, 127);

function admin_timeout(data: adminData) {
    return data.time !== Date.now() * 100 && Date.now() > data.time;
}
class admin {
    static backend_bound = world.addZone({
        bounds: new GameBounds3(
            new GameVector3(37, 47, 119),
            new GameVector3(47, 57, 135)
        ),
    });

    /**在后台吗？ */
    static inBackend(entity: GamePlayerEntity) {
        return this.backend_bound.entities().includes(entity);
    }

    /**补课可以删除的人 */
    static cannotDelete(userId: string) {
        return admin_setup.map((e) => e.userId).includes(userId);
    }
    /**检测是否过期的 */
    /**
     * 检测是否过期
     * @param data
     * @returns
     */
    static timeout(data: adminData) {
        return data.time !== Date.now() * 100 && Date.now() > data.time;
    }

    static getBlackPlayer() {
        return admin_data.filter(
            (e) => e.admin === ADMIN_TYPE.BLACK && !admin_timeout(e)
        );
    }

    /**
     * 添加管理员/处罚
     * @param userId
     * @param name
     * @param admin
     * @param time
     */
    static add(
        userId: string,
        name: string,
        admin: ADMIN_TYPE,
        time: number = Date.now(),
        avatar?: string
    ) {
        if (this.cannotDelete(userId)) {
            return;
        } // 不可删除/操作就跳过
        const addObject = { userId, name, admin, time, avatar };

        admin_data.push(addObject);
        admin_data = admin_data.filter((e) => !admin_timeout(e));
        adminStorage?.update('admin', (data) => {
            const plainObject = {
                userId: addObject.userId,
                name: addObject.name,
                admin: addObject.admin,
                time: addObject.time,
                avatar: addObject.avatar,
            };
            if (data) {
                const arr = Array.isArray(data.value)
                    ? data.value.filter((e) => !admin_timeout(e))
                    : [];
                arr.push(plainObject);
                console.log(arr.map((e) => e.name));
                return arr;
            }
            // Return a default value if data is undefined
            return [plainObject];
        });

        // 运行对应的程序
        const findPlayer = findOnlineId(userId);
        if (findPlayer) {
            this.run(findPlayer);
        }
    }

    /**
     * 过去管理员数据
     * @returns 管理员数据
     */
    static getAdmin() {
        return admin_data;
    }

    /**
     * 职位是否对上
     * @param entity
     * @param admin
     * @returns
     */
    static isAdmin(entity: GamePlayerEntity, admin: string) {
        return admin_data.find(
            (a) =>
                a.userId === entity.player.userId &&
                a.admin === admin &&
                !admin_timeout(a)
        );
    }

    /**
     * 是否是管理员，只要是就返回（拉黑的跳过）
     * @param entity
     * @returns
     */
    static isAdmin_(entity: GamePlayerEntity) {
        return admin_data.find(
            (a) =>
                a.userId === entity.player.userId &&
                a.admin !== ADMIN_TYPE.BLACK &&
                !admin_timeout(a)
        );
    }

    /**
     * 前往后台
     * @param entity
     */
    static gotoBackend(entity: GamePlayerEntity) {
        entity.position.copy(backend_pos);
    }

    /**
     * 离开后台
     * @param entity
     */
    static leaveBackend(entity: GamePlayerEntity) {
        entity.position.set(48, 46, 126);
    }

    /**
     * findUserId
     * @param userId
     * @returns
     */
    static find(userId: string) {
        const list = admin_data;
        return list.find((item: adminData) => item.userId === userId);
    }

    /**
     * 删除拉黑
     * @param userId
     */
    static async deleteBlack(userId: string) {
        if (this.cannotDelete(userId)) {
            return;
        } // 不可删除/操作就跳过
        // console.log(admin_data.filter((e) => (e.admin === ADMIN_TYPE.BLACK && e.userId === userId)));
        admin_data = admin_data.filter(
            (e) => !(e.admin === ADMIN_TYPE.BLACK && e.userId === userId)
        );
        adminStorage?.update('admin', (data) => {
            if (data) {
                let { value } = data;
                if (Array.isArray(value)) {
                    value = value.filter(
                        (e) =>
                            !(
                                e.admin === ADMIN_TYPE.BLACK &&
                                e.userId === userId
                            )
                    );
                    return value;
                }
                console.log('不是一个列表。');
            }
            // Return a default value if data is undefined
            return [];
        });
    }

    /**删除所有关于 */
    static async deleteAdmin(userId: string) {
        if (this.cannotDelete(userId)) {
            return;
        } // 不可删除/操作就跳过
        admin_data = admin_data.filter((e) => !(e.userId === userId));
        adminStorage?.update('admin', (data) => {
            if (data) {
                let { value } = data;
                if (Array.isArray(value)) {
                    value = value.filter((e) => !(e.userId === userId));
                }
                return value;
            }
            // Return a default value if data is undefined
            return [];
        });
    }

    /**
     * update
     */
    static updateTemp() {
        adminStorage?.get('admin').then((data) => {
            const updateData = (data?.value as unknown as adminData[]) || [];
            // console.log('过滤前', data?.value.map(e => e.name + e.time), data?.value.map(e => admin_timeout(e)));
            admin_data = [
                ...admin_setup,
                ...updateData.filter((e) => !admin_timeout(e)),
            ];
            // console.log('过滤后', data?.value.filter((e) => !admin_timeout(e)).map(e => e.name));

            world.querySelectorAll('player').forEach((e) => admin.run(e));
        });
    }

    /**
     * 执行处罚程序
     * @param entity
     */
    static run(entity: GamePlayerEntity) {
        if (this.isAdmin(entity, ADMIN_TYPE.BLACK)) {
            // 执行拉黑惩罚
            entity.player.kick();
        }
        const allAdminButton = [
            '收麦克风',
            '给麦克风',
            '下舞台',
            '上舞台',
            'Black',
            'deleteBlack',

            'Kick',

            '删除镜头追踪',
            '镜头追踪',

            '音频控制',
            '服务器',
            '流程操作',
            '人员管理',

            '发言处罚',

            '背景音乐',
            '音效',
            '解除拉黑',
        ];

        const PATROL_button = [
            '收麦克风',
            '下舞台',
            'Black',
            'deleteBlack',
            'Kick',
            '服务器',
            '解除拉黑',
        ];

        // 如果是后台管理
        if (this.isAdmin(entity, ADMIN_TYPE.BACKEND)) {
            showScreen(entity, 'adminScreen');
            hideUI(entity, 'adminScreen', '人员管理');
            if (this.inBackend(entity)) {
                for (const i of allAdminButton) {
                    showUI(entity, 'adminScreen', i);
                }
                hideUI(entity, 'adminScreen', '前往后台');
            } else {
                showUI(entity, 'adminScreen', '前往后台');
                for (const i of allAdminButton) {
                    if (PATROL_button.includes(i)) {
                        showUI(entity, 'adminScreen', i);
                    } else {
                        hideUI(entity, 'adminScreen', i);
                    }
                }
            }
        }
        // 如果是人员管理
        else if (this.isAdmin(entity, ADMIN_TYPE.PEOPLE)) {
            showScreen(entity, 'adminScreen');
            if (this.inBackend(entity)) {
                for (const i of allAdminButton) {
                    showUI(entity, 'adminScreen', i);
                }
                hideUI(entity, 'adminScreen', '前往后台');
            } else {
                showUI(entity, 'adminScreen', '前往后台');
                showUI(entity, 'adminScreen', '人员管理');
                for (const i of allAdminButton) {
                    if (PATROL_button.includes(i)) {
                        showUI(entity, 'adminScreen', i);
                    } else {
                        hideUI(entity, 'adminScreen', i);
                    }
                }
            }
        }
        // 如果是巡逻管理
        else if (this.isAdmin(entity, ADMIN_TYPE.PATROL)) {
            showScreen(entity, 'adminScreen');
            hideUI(entity, 'adminScreen', '前往后台');
            hideUI(entity, 'adminScreen', '人员管理');
            for (const i of allAdminButton) {
                if (PATROL_button.includes(i)) {
                    showUI(entity, 'adminScreen', i);
                } else {
                    hideUI(entity, 'adminScreen', i);
                }
            }
        } else {
            hideScreen(entity, 'adminScreen');
        }
    }
}

const backend_leave = world.querySelectorAll('.后台');
backend_leave.forEach((e) => {
    e.enableInteract = true;
    e.interactHint = '离开后台';
    e.nameRadius = 16;
    e.showEntityName = true;
    e.customName = '离开';
    e.interactRadius = 3;
    e.onInteract(({ entity }) => {
        admin.leaveBackend(entity);
    });
});

setInterval(admin.updateTemp, 3 * 1000);
setInterval(() => {
    world.querySelectorAll('player').forEach((e) => {
        admin.run(e);
    });
}, 400);

world.onPlayerJoin(({ entity }) => {
    admin.run(entity);
    entity.player.onKeyDown(({ keyCode }) => {
        if (keyCode === 71 && admin.isAdmin(entity, ADMIN_TYPE.CAMERA)) {
            // 71： G
            const state = !entity.player.spectator;
            entity.player.spectator = state;
            entity.player.showName = !state;
            entity.player.invisible = state;
            entity.player.runSpeed = state ? 0.9 : 0.4;
        }
    });
});

/**主持人类 */
class host {
    static microphone = world.querySelectorAll('.麦克风');

    /**
     * 是否是主持人
     * @param entity
     * @returns
     */
    static isHost(entity: GamePlayerEntity) {
        if (this.zone(entity)) {
            return this.zone(entity)?.id;
        } else if (this.hold(entity)) {
            return '手持麦';
        } else {
            return false;
        }
    }

    /**
     * 是否靠近麦克风
     * @param entity
     * @returns
     */
    static zone(entity: GamePlayerEntity) {
        const near = this.microphone.find(
            (e) => entity.position.distance(e.position) < 3
        );
        return near;
    }

    /**
     * 是否手握麦克风
     * @param entity
     * @returns
     */
    static hold(entity: GamePlayerEntity) {
        const findWear = entity.player
            .wearables()
            .find((e) => e.mesh === 'mesh/麦克风.vb');
        return findWear;
    }

    /**
     * 给予麦克风
     * @param entity
     * @returns
     */
    static give(entity: GamePlayerEntity) {
        return entity.player.addWearable({
            mesh: 'mesh/麦克风.vb',
            scale: new GameVector3(0.8, 0.8, 0.8),
            bodyPart: GameBodyPart.RIGHT_HAND,
            offset: new GameVector3(0, 0, 0.1),
            orientation: new GameQuaternion(0, 0, 0, 1),
        });
    }

    /**
     * 销毁麦克风
     * @param entity
     */
    static delete(entity: GamePlayerEntity) {
        const findWearList = entity.player
            .wearables()
            .filter((e) => e.mesh === 'mesh/麦克风.vb');
        findWearList.forEach((e) => {
            entity.player.removeWearable(e);
        });
    }
}

/**舞台类 */
class stage {
    /**是否可以在舞台内 */
    static canInStage = false;
    static zone = world.addZone({
        bounds: new GameBounds3(
            new GameVector3(115, 13, 107),
            new GameVector3(135, 1000, 146)
        ),
    });
    static host_: string[] = [];
    static goStagePos = new GameVector3(167, 25, 127);
    /**用户是否在此区域 */
    static inZone(entity: GamePlayerEntity) {
        return this.zone.entities().includes(entity);
    }

    /**传送至舞台 */
    static goto(entity: GamePlayerEntity) {
        if (!this.host_.includes(entity.player.name)) {
            this.host_.push(entity.player.name);
        }
        entity.position.copy(this.goStagePos);
    }

    /** 强制下去 */
    static away(entity: GamePlayerEntity) {
        if (this.host_.includes(entity.player.name)) {
            this.host_.splice(this.host_.indexOf(entity.player.name), 1);
        }
        entity.velocity.copy(
            new GameVector3(-2, 0.3, -0.5 + Math.random() * 1).scale(10)
        );
    }

    /** */
    static tryToStage(entity: GamePlayerEntity) {
        if (host.isHost(entity)) {
            return;
        }
        if (
            !this.canInStage &&
            this.inZone(entity) &&
            !this.host_.includes(entity.player.name)
        ) {
            entity.velocity.copy(
                new GameVector3(-2, 0.3, -0.5 + Math.random() * 1).scale(10)
            );
        }
    }
}

stage.zone.onEnter(({ entity }) => {
    stage.tryToStage(entity as GamePlayerEntity);
});

setInterval(() => {
    world.querySelectorAll('player').forEach((e) => {
        stage.tryToStage(e);
    });
}, 200);

async function select(
    entity: GamePlayerEntity,
    title: string,
    content: string,
    options: string[]
) {
    return await entity.player?.dialog({
        type: GameDialogType.SELECT,
        title,
        content,
        options,
    });
}
async function input(entity: GamePlayerEntity, title: string, content: string) {
    return await entity.player?.dialog({
        type: GameDialogType.INPUT,
        title,
        content,
    });
}

async function addAdmin(entity: GamePlayerEntity) {
    if (!admin.isAdmin(entity, ADMIN_TYPE.PEOPLE)) {
        return;
    }
    const backend = admin_data.filter((e) => e.admin === ADMIN_TYPE.BACKEND);
    // const black = admin_data.filter(e => e.admin === ADMIN_TYPE.BLACK);
    const patrol = admin_data.filter((e) => e.admin === ADMIN_TYPE.PATROL);
    const peo = admin_data.filter((e) => e.admin === ADMIN_TYPE.PEOPLE);
    const text = `后台: ${backend.map((e) => e.name)}\n巡逻: ${patrol.map((e) => e.name)}\n人员管理:${peo.map((e) => e.name)}`;
    const addOrDelete = await select(entity, '管理员', `${text}`, [
        '添加',
        '删除',
    ]);

    if (!addOrDelete) {
        return;
    }

    if (addOrDelete.value === '添加') {
        const typeResult = await select(
            entity,
            '添加管理员',
            '请问你要添加什么类型的管理员？',
            Object.values(ADMIN_TYPE).filter((e) => e !== ADMIN_TYPE.BLACK)
        );
        if (!typeResult) {
            return;
        }
        const players = world.querySelectorAll('player');
        const selPlayerRes = await select(entity, '添加管理员', '请选择玩家', [
            '手动输入',
            ...players.map((e) => `${e.player.name}(${e.player.userId})`),
        ]);
        if (!selPlayerRes) {
            return;
        }
        if (selPlayerRes.index === 0) {
            const iptPlayer = await input(
                entity,
                '添加管理员',
                `请输入添加管理的UID。`
            );
            const iptPlayerName = await input(
                entity,
                '添加管理员',
                `请输入添加管理的名字。`
            );
            if (!iptPlayer || !iptPlayerName) {
                return;
            }
            admin.add(
                iptPlayer,
                iptPlayerName,
                typeResult.value as ADMIN_TYPE,
                Date.now() * 100,
                '没有'
            );
        } else {
            const selPlayer = players[selPlayerRes.index - 1];
            admin.add(
                selPlayer.player.userId,
                selPlayer.player.name,
                typeResult.value as ADMIN_TYPE,
                Date.now() * 100,
                selPlayer.player.avatar
            );
        }
    } else {
        // 删除
        const players = world.querySelectorAll('player');
        const selPlayerRes = await select(
            entity,
            '添加管理员',
            '请选择玩家',
            admin_data.map((e) => e.name)
        );
        if (!selPlayerRes) {
            return;
        }
        const selPlayer = players[selPlayerRes.index];
        admin.deleteAdmin(selPlayer.player.userId);
    }
}

admin.backend_bound.onEnter(({ entity }) => {
    admin.run(entity as GamePlayerEntity);
});

type ActivityFn = { func: () => void; count: number };

/**活动状态管理类 */
const allActivities: Record<string, ActivityFn> = {
    灯光秀: {
        func: light_show,
        count: 0,
    },
    开场秀: {
        func: voxel_countdown,
        count: 0,
    },
};

// 客户端发送请求
remoteChannel.onServerEvent(async ({ entity, args }) => {
    if (!admin.isAdmin_(entity)) {
        return;
    }
    if (args.type === 'Kick') {
        const findUser = findOnlineId(args.data);
        findUser?.player.kick();
    }

    if (args.type === 'Black') {
        const findUser = findOnlineId(args.data);
        admin.add(
            args.data,
            findUser?.player.name as string,
            ADMIN_TYPE.BLACK,
            Date.now() * 100,
            findUser?.player.avatar
        );
    }
    if (args.type === 'DeleteBlack') {
        console.log('解除拉黑', args.data);
        admin.deleteAdmin(args.data);
    }
    if (args.type === 'activity_button') {
        if (args.data in allActivities) {
            allActivities[args.data].func();
            allActivities[args.data].count++;
        }
    }
    if (args.type === 'sound_button') {
        world.sound(args.data);
    }
    if (args.type === 'bgm_button') {
        world.ambientSound = args.data;
    }
    if (args.type === 'onStage') {
        const f = findOnlineId(args.data);
        if (f) {
            stage.goto(f);
        }
    }
    if (args.type === 'awayStage') {
        const f = findOnlineId(args.data);
        if (f) {
            stage.away(f);
        }
    }
    if (args.type === 'giveMai') {
        const f = findOnlineId(args.data);
        if (f) {
            host.give(f);
        }
    }
    if (args.type === 'awayMai') {
        const f = findOnlineId(args.data);
        if (f) {
            host.delete(f);
        }
    }

    if (args.type === 'server_button') {
        world.teleport(getMapId(), [entity], args.data);
    }

    if (args.type === '人员管理') {
        addAdmin(entity);
    }
    if (args.type === '前往后台') {
        admin.gotoBackend(entity);
    }
    if (args.type === '发言处罚') {
        // chat.muted = !chat.muted;
        // eslint-disable-next-line no-use-before-define
        chat.chatMuted();
    }
});

setInterval(() => {
    const backend_user = world
        .querySelectorAll('player')
        .filter((e) => admin.isAdmin_(e));
    sendClient(backend_user, 'DeleteBlack', admin.getBlackPlayer()); // 删除拉黑
    sendClient(
        backend_user,
        'activity_button',
        Object.keys(allActivities).map((e) => {
            return {
                name: e,
                userId: `使用${allActivities[e].count}次`,
                avatar: '暂无',
            };
        })
    ); // ; //
    sendClient(
        backend_user,
        'awayMai',
        world
            .querySelectorAll('player')
            .filter((e) => host.hold(e))
            .map((e) => {
                return {
                    name: e.player.name,
                    userId: e.player.userId,
                    avatar: e.player.avatar,
                };
            })
    ); // ; //
    sendClient(
        backend_user,
        'awayStage',
        world
            .querySelectorAll('player')
            .filter((e) => stage.inZone(e))
            .map((e) => {
                return {
                    name: e.player.name,
                    userId: e.player.userId,
                    avatar: e.player.avatar,
                };
            })
    ); //
    // sendClient(backend_user, 'delete_camera_targets', ); //
    sendClient(
        backend_user,
        'bgm_button',
        resources
            .ls('audio')
            .sort((a, b) => a.path.length - b.path.length)
            .map((e) => {
                return {
                    // 有点特殊。
                    name: e.path.split('/')[1],
                    userId: e.path,
                    avatar: '暂无', // 这个必须有
                };
            })
    ); //
    sendClient(
        backend_user,
        'sound_button',
        resources
            .ls('audio')
            .sort((a, b) => b.path.length - a.path.length)
            .map((e) => {
                return {
                    // 有点特殊。
                    name: e.path.split('/')[1],
                    userId: e.path,
                    avatar: '暂无', // 这个必须有
                };
            })
    ); //
}, 200);

world.querySelectorAll('.麦克风').forEach((e) => {
    e.interactRadius = 3;
    e.enableInteract = true;
    e.showEntityName = true;
    e.nameRadius = 5;
});

world.onInteract(({ entity, targetEntity }) => {
    if (targetEntity.hasTag('麦克风')) {
        if (host.hold(entity)) {
            host.delete(entity);
        } else {
            host.give(entity);
        }
    }
});

/** 主持人 发言框 */
world.onChat(({ entity, message }) => {
    const hostType = host.isHost(entity as GamePlayerEntity);
    if (entity.player && hostType) {
        sendClient(
            world.querySelectorAll('player') as GamePlayerEntity[],
            'chat',
            {
                entity: {
                    id: entity.player.userId,
                    name: entity.player.name,
                    avatar: entity.player.avatar,
                },
                message,
                type: hostType,
            }
        );
    }
});

const mapStorage = storage.getGroupStorage<boolean>('map');

/**限制字数 禁言处罚*/
class chat {
    static getStorage() {}

    static continuous: {
        userId: string;
        name: string;
        time: number;
        number: number;
    }[] = [];
    static muted = false;
    static muted_time = 3 * 1000 * 60;
    static muted_number = 3; // 可发言次数，等于此次数踢出服务器，超过此次数直接拉黑。
    // static word_num = {};

    static chatMuted() {
        this.muted = !this.muted;
        mapStorage?.set('muted', this.muted);
        this.setupContinuous();
    }

    static async getStorageMuted() {
        const data = await mapStorage?.get('muted');
        if (data && data.value) {
            this.muted = data.value;
        }
    }

    /**重置聊天次数 */
    static setupContinuous() {
        this.continuous = [];
    }

    /**
     * 查找该玩家的违规记录
     * @param userId
     * @returns
     */
    static findRecord(userId: string) {
        const findPlayer = this.continuous.find((e) => e.userId === userId);
        if (findPlayer && Date.now() - findPlayer?.time > this.muted_time) {
            findPlayer.number = 0;
        }
        return findPlayer;
    }

    /**
     *
     * @param data
     * @returns
     */
    static timeout(data: {
        userId: string;
        name: string;
        time: number;
        number: number;
    }) {
        return Date.now() - data.time > this.muted_time;
    }

    /**
     * add
     * @param userId
     * @param name
     * @param number
     * @returns
     */
    static add(userId: string, name: string, number: number) {
        if (this.findRecord(userId)) {
            return;
        }
        this.continuous.push({ userId, name, time: Date.now(), number });
    }

    /**
     * update
     * @param userId
     * @param name
     * @returns
     */
    static update(userId: string, name: string) {
        if (!this.findRecord(userId)) {
            this.add(userId, name, 0);
        }

        const data = this.findRecord(userId);
        if (!data) {
            return;
        }
        if (this.timeout(data)) {
            data.number = 1;
            data.time = Date.now();
        } else {
            data.number++;
        }
        // this.findRecord(userId).number ++;
    }

    /**
     * 处罚
     * @param entity
     * @returns
     */
    static run(entity: GamePlayerEntity) {
        const data = this.findRecord(entity.player.userId);
        if (!data) {
            return;
        }
        if (data.number === this.muted_number) {
            entity.player.kick();
            world.say(
                `@${entity.player.name} 因发言数量过多，违反地图规则，踢出地图`
            );
        } else if (data.number > this.muted_number) {
            world.say(
                `@${entity.player.name} 因发言数量过多，违反地图规则，拉黑10分钟。`
            );
            admin.add(
                entity.player.userId,
                entity.player.name,
                ADMIN_TYPE.BLACK,
                Date.now() + 10 * 1000 * 60,
                entity.player.avatar
            );
        }
    }

    /**
     *
     * @param entity
     * @param message
     * @returns
     */
    static chat(entity: GamePlayerEntity, message: string) {
        if (host.isHost(entity as GamePlayerEntity)) {
            return;
        }
        if (admin.isAdmin_(entity)) {
            return;
        }

        if (this.muted) {
            entity.player.directMessage(
                '当前处于 发言处罚 状态, 若您再发言，可能会受到处罚（无法再进入地图）！！！！'
            );
            this.update(entity.player.userId, entity.player.name);
            this.run(entity);
        }

        /**刷屏检测 */
        if (message.length > 500) {
            // 禁言处罚
            entity.player?.dialog({
                type: GameDialogType.SELECT,
                title: '系统警告',
                content: '您的字数超过500字，已被强制踢出地图',
                options: ['确定'],
            });
            world.say(
                '@' +
                    entity.player.name +
                    '因发送长文本内容被强制踢出地图，并采取拉黑处罚。'
            );
            admin.add(
                entity.player.userId,
                entity.player.name,
                ADMIN_TYPE.BLACK,
                Date.now() + 10 * 1000 * 60,
                entity.player.avatar
            );
        }
        if (message.length > 300) {
            // 禁言处罚
            entity.player?.dialog({
                type: GameDialogType.SELECT,
                title: '系统警告',
                content: '您好，建议您发送的字数控制在300字内。',
                options: ['确定'],
            });
        }
    }
}

setInterval(() => {
    chat.getStorageMuted();
}, 3000);

setInterval(() => {
    world.querySelectorAll('player').forEach((e) => {
        if (chat.muted) {
            showUI(e, 'screen', 'muted');
        } else {
            hideUI(e, 'screen', 'muted');
        }
    });
}, 200);

world.onChat(({ entity, message }) => {
    chat.chat(entity as GamePlayerEntity, message);
});
